<!DOCTYPE html>
<html>
<head>
    <title>Skoop: {{.DiagnoseInfo}} </title>

    <script>
        function getElementLeft(element) {
            return element.getBoundingClientRect().left
        }

        function getElementBottom(element) {
            return element.getBoundingClientRect().top + element.getBoundingClientRect().height
        }

        function init() {
            let side = document.getElementById("side")
            let mask = side.querySelector(".side-panel-mask")
            mask.onclick = e => {
                hideSlidePanel()
            }
        }


        let cluster_info = JSON.parse('{{.Cluster}}')
        let node_info = JSON.parse('{{.Nodes}}')
        let edge_info = JSON.parse('{{.Edges}}')

        function hideSlidePanel() {
            let side = document.getElementById("side")
            let mask = side.querySelector(".side-panel-mask")
            let panel = side.querySelector(".side-panel")

            mask.style.opacity = 0
            panel.style.right = "-400px"
            setTimeout(() => {
                side.style.display = "none"
            }, 200)
        }
        function showSlidePanel(title, info, suspicions, show_suspicions) {
            let side = document.getElementById("side")
            let header = side.querySelector(".side-panel-header")
            header.innerHTML = title

            let panel_info = side.querySelector(".side-panel-info")
            if (info.length !== 0) {
                let info_inner = ""
                info.forEach(i => {
                    info_inner += `<div class="side-panel-info-item">
                        <div class="side-panel-info-item-name">${i[0]}</div>
                        <div class="side-panel-info-item-value">${i[1]}</div>
                    </div>`
                });
                panel_info.innerHTML = info_inner
            } else {
                panel_info.style.display = "none"
            }


            let panel_suspicion = side.querySelector(".side-panel-suspicion")
            if (show_suspicions) {
                let suspicion_items = panel_suspicion.querySelector(".side-panel-suspicion-items")
                if (suspicions) {
                    let items_inner = ""
                    suspicions.forEach(s => {
                        items_inner += `<div class="side-panel-suspicion-item">
                            <span class="side-panel-suspicion-item-level color-${s.level.toLowerCase()}">${s.level}</span>
                            <span class="side-panel-suspicion-item-message">${s.message}</span>
                        </div>`
                        suspicion_items.innerHTML = items_inner
                    })
                } else {
                    suspicion_items.innerHTML = 'There is no suspicion on this node.'
                }
                panel_suspicion.style.display = "block"
            } else {
                panel_suspicion.style.display = "none"
            }

            let mask = side.querySelector(".side-panel-mask")
            let panel = side.querySelector(".side-panel")
            side.style.display = "block"
            setTimeout(() => {
                mask.style.opacity = 0.5
                panel.style.right = "0"

            }, 0)
        }

        function patchNodeInfo(elem, n) {
            console.log(`patching ${n.id}`)
            let text = elem.querySelector("text")
            console.log(`text: ${text}`)
            node_name = text.innerHTML
            // calculate x, y and width
            let ellipse = elem.querySelector("ellipse")
            let d = Math.SQRT2 * ellipse.rx.baseVal.value
            let x = ellipse.cx.baseVal.value - 0.5 * d;
            let y = ellipse.cy.baseVal.value - 0.5 * d;

            let object = `<foreignObject class="node-display" width="${d}" height="${d}" x="${x}" y="${y}">
                <img style="width: 40%" src="./svg/${n.type}.svg" />
                <p class="node-name">${node_name}</p>
                <div class="node-suspicion-counter color-${n.suspicion_level.toLowerCase()}">${n.suspicions ? n.suspicions.length : 0}</div>
                </foreignObject>`

            text.remove();
            elem.innerHTML += object
        }


        function applyCluster() {
            cluster_suspicion = document.getElementById("cluster-suspicions")
            cluster_suspicion.onclick = ev => {
                showSlidePanel(`Cluster`, [], cluster_info.suspicions, true)
            }

            counter = `<span style="display: inline-block; text-align: center;"
                             class="node-suspicion-counter color-${cluster_info.suspicion_level.toLowerCase()}">
                                ${cluster_info.suspicions ? cluster_info.suspicions.length : 0}
                       </span>`
            cluster_suspicion.innerHTML += counter
        }

        function applyNodes() {
            node_info.forEach(n => {
                let node = document.getElementsByClassName(`node ${n.id}`)[0]
                patchNodeInfo(node, n)
                node.classList.add("node-" + n.suspicion_level.toLowerCase())
                node.onclick = e => {
                    showSlidePanel(`Node ${n.id}`, [["Node ID", n.id], ["Type", n.type]], n.suspicions, true)
                    e.cancelBubble = true
                }
            });
        }

        function applyEdges() {
            edge_info.forEach(e => {
                let edge = document.getElementsByClassName(`edge ${e.id}`)[0]
                edge.onclick = ev => {
                    showSlidePanel(`Edge ${e.id}`, [
                        ["Edge ID", e.id],
                        ["Type", e.type],
                        ["Action", e.action],
                        ["Output Interface (Sender Node)", e.oif],
                        ["Input Interface (Receiver Node)", e.iif],
                        ["Packet Source", e.packet.src],
                        ["Packet Destination", e.packet.dst],
                        ["Packet Destination Port", e.packet.dport],
                        ["Packet Protocol", e.packet.protocol]
                    ], null, false)
                    ev.cancelBubble = true
                }
            })
        }


        document.addEventListener("DOMContentLoaded", _ => {
            init()
            applyCluster()
            applyNodes()
            applyEdges()
        })


    </script>
    <style>
        body {
            margin: 0;
        }

        .skoop-header {
            display: flex;
            align-items: center;
            background-color: #444CCB;
            color: white;
            top: 0;
            height: 44px;
            min-height: 44px;
            padding-left: 10px;
        }

        #graph {
            display: flex;
            justify-content: center;
            max-width: 1800px;
            width: 100%;
            margin: auto;
        }

        svg {
            width: 90%;
            height: auto;
        }

        .node,
        .edge {
            pointer-events: fill;
            cursor: pointer;
        }

        .edge text {
            user-select: none;
        }

        .node ellipse {
            stroke-width: 1px;
            stroke: #666666;
            transition: 100ms;
        }

        .node:hover ellipse {
            stroke-width: 2px !important;
            transition: 200ms;
        }

        .edge:hover path {
            stroke-width: 2px !important;
            transition: 200ms;
        }

        .node-name {
            margin: 0;
            font-size: 12px;
            line-break: anywhere;
            text-align: center;
        }

        .node-display {
            text-align: center;
        }

        .node-suspicion-counter {
            margin: auto;
            font-size: 12px;
            height: 16px;
            width: 16px;
            border: 1px gray;
            border-radius: 3px;
        }

        .color-info {
            background-color: #30BD61;
        }

        .color-warning {
            background-color: #FFB369;
        }

        .color-fatal,
        .color-critical {
            background-color: #F76D76;
        }

        .side {
            display: none;
        }

        .side-panel {
            position: fixed;
            top: 44px;
            right: -400px;
            width: 400px;
            height: 100%;
            border-left: 1px solid #fafafa;
            background-color: #ffffff;
            transition: right 0.2s;
        }

        .side-panel-header {
            padding: 13px 16px;
            border-bottom: 1px solid #cccccc;
        }

        .side-panel-mask {
            position: fixed;
            top: 44px;
            right: 0;
            width: 100%;
            height: 100%;
            background-color: black;
            opacity: 0;
            transition: all .2s;
        }

        .side-panel-info-item {
            margin: 15px 20px;
            font-size: 13px;
        }

        .side-panel-info-item-name {
            color: gray;
        }

        #suspicions {
            display: none;
            width: 400px;
            background-color: white;
            position: absolute;
            min-height: 100px;
            border: 1px solid gray;
        }

        #suspicions-list p {
            margin: 0 3px 3px 3px;
            border: 1px solid gray;
        }

        #suspicions-header {
            background-color: #444CCB;
            color: white;
            height: 30px;
            align-items: center;
            margin: 0;
            padding-left: 5px;
            white-space: nowrap;
        }

        #diagnose-result {
            display: flex;
            align-items: center;
            justify-content: center;
            min-width: 1000px;
            min-height: 1000px;
        }

        .side-panel-suspicion {
            border-top: 1px solid #cccccc;
        }

        .side-panel-suspicion-header {
            margin: 15px 15px;
            font-size: 15px;
        }

        .side-panel-suspicion-items {
            margin: 15px 30px 15px 26px;
        }

        .side-panel-suspicion-item {
            margin-top: 20px;
        }

        .side-panel-suspicion-item-level {
            user-select: none;
            color: white;
            padding: 1px 5px;
            border-radius: 5px;
            font-size: 13px;
        }

        .side-panel-suspicion-item-message {
            line-break: loose;
            font-size: 15px;
        }

        #cluster-suspicions {
            cursor: pointer;
            margin-left: 10px;
            padding: 3px;
            border: 1px solid #fafafa;
            border-radius: 7px;
        }

        .node-display .node-suspicion-counter {
            margin-top: 3px;
        }
    </style>
</head>

<body>
    <header class="skoop-header">
        <div id="title">Skoop {{.DiagnoseInfo}}</div>
        <div id="cluster-suspicions">
            <span>Cluster Suspicions</span>
        </div>
    </header>
    <div id="diagnose-result">
        {{.GraphSvg}}
    </div>
    <div class="side" id="side">
        <div class="side-panel-mask"></div>
        <div class="side-panel">
            <div class="side-panel-header">Diagnose Result:</div>
            <div class="side-panel-info">
            </div>
            <div class="side-panel-suspicion">
                <div class="side-panel-suspicion-header">Suspicions:</div>
                <div class="side-panel-suspicion-items">
                </div>
            </div>
        </div>
    </div>
</body>

</html>
